package com.security.lambda.filter;

import io.swagger.models.auth.In;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * ${DESCRIPTION}
 *
 * @author roger
 * @email 190642964@qq.com
 * @create 2017-11-10 14:58
 **/
public class Main {

    public static void main(String[] args) {

        // Lambda 表达式
        BiFunction<String, Integer, Menu> menuBiFunction = (String name, Integer calories) -> new Menu(name, calories);
        // 方法引用
        BiFunction<String, Integer, Menu> stringIntegerMenuBiFunction = Menu::new;

        List<Menu> menus = new ArrayList<>();
        menus.add(menuBiFunction.apply("牛肉", 20));
        menus.add(menuBiFunction.apply("猪肉", 50));
        menus.add(menuBiFunction.apply("土豆", 10));
        menus.add(menuBiFunction.apply("白菜", 5));

        menus.stream()
                .filter(menu -> menu.getCalories() < 20)
                .sorted(Comparator.comparing(Menu::getCalories))
                .map(Menu::getName)
                .collect(Collectors.toList()).stream().forEach(menu -> System.out.println(menu));

        System.out.println();

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 8);
        numbers.stream()
                .filter(integer -> integer % 2 == 0)
                .distinct() // 去重，重写hashCode和equals方法
//                .limit(2) // 不超过指定长度的流
//                .skip(2) // 跳过前面2个，返回后面的流
                .forEach(integer -> System.out.println(integer));

        System.out.println();

        List<String> words = Arrays.asList("Hello", "World");

        words.stream()
                // 返回由字母构成的数组
                .map(word -> word.split(""))
                .distinct()
                .collect(Collectors.toList())
                .forEach(word -> System.out.println(word));

        words.stream()
                // 返回由字母构成的数组
                .map(word -> word.split(""))
                //  Arrays.stream() 接受一个数组并产生一个流
                .map(Arrays::stream)
                .distinct()
                .collect(Collectors.toList())
                .forEach(word -> System.out.println(word));

        words.stream()
                // 返回由字母构成的数组
                .map(word -> word.split(""))
                //  Arrays.stream() 接受一个数组并产生一个流
                // flatMap() 扁平化一个流,将各个数组映射成流的内容
                .flatMap(Arrays::stream)
                .distinct()
                .collect(Collectors.toList())
                .forEach(word -> System.out.println(word));

        /************************************************************/
        System.out.println();

        // 返回该列表的 二次方列表
        List<Integer> square = Arrays.asList(1, 2, 3, 4, 5);
        square.stream()
                .map(number -> number * number)
                .collect(Collectors.toList())
                .forEach(number -> System.out.print(number + " , "));
        System.out.println();

        // number1 和 number 2 返回([(1,3),(1,4),(2,3),(2,4),(3,3),(3,4)])
        List<Integer> number1 = Arrays.asList(1, 2, 3);
        List<Integer> number2 = Arrays.asList(3, 4);
        number1.stream()
                .flatMap(i -> number2.stream()
                        .map(j -> new Integer[]{i, j}))
                .collect(Collectors.toList())
                .forEach(p -> System.out.println("(" + p[0] + "," + p[1] + ")"));

        System.out.println();
        // number1 和 number 2 返回 和 为3的倍数
        number1.stream()
                .flatMap(i -> number2.stream()
                        .filter(j -> (i + j) % 3 == 0)
                        .map(j -> new Integer[]{i, j}))
                .collect(Collectors.toList())
                .forEach(p -> System.out.println("(" + p[0] + "," + p[1] + ")"));


        menus.stream()
                .map(menu -> new Integer(menu.getCalories()))
                .collect(Collectors.toList())
                .forEach(p -> System.out.println(p));
    }

}
